{-
	Main Module
	
	r51
	
	29 March 2010
	
	Daniel De Guzman
	
	This module is part of the FPT Algorithm Implementation Project for the Massey University
	paper: 159.402 Programming Languages. A summary of the program is outlined below.
	
	A. Preliminary Phase
		I. 	File Processing
				When a file has been loaded, the main method first checks the file format for
				any irregularities. It looks at the following:
					-	File extension, and
					-	File Format:
							- Check first line for K, and check if it is a digit,
							- Check second line for number of vertices and check if it 
							  is a digit,
							- Compare the second line's value to the actual number of 
							  enumerated vertices, and
							- Check each enumerated vertex e.g. "A, B C D"
		
		II.	Graph Creation
				Once the file has been validated, the program can start creating the graph.
				Currently, it outputs a series of strings to show that the graph has been
				created successfully.
		
		III.Kernelization
				The Kernelization phase of the project is implemented upon the created graph.
				The program returns the new k, graph and vertex cover. The kernelization
				rules are as follows:
					Rule #1 Delete any isolated vertex from the graph
					Rule #2 Remove any vertex with degree 1 from the graph
					Rule #3 Add any vertex that is greater than the parameter k.
				
				It must be noted that the algorithm is applied recursively until there is no
				longer any graph entry that meets the criteria.  Also, each time a vertex is
				added to the vertex cover, the parameter k is reduced by one and all 
				occurrences of the vertices are removed from the graph.
				
		IV. File Creation
				An output file is created which shows the before and after graphs.
	
	B. Final Program
		The final program must also implement the Bound Search Algorithm. In order to find
		the vertex cover, the following rules must be followed:
			Rule #1 If there is a vertex of degree 1, add its neighbour to the vertex cover
			Rule #2 If there is a vertex of degree 2, either
						a. Both neighbours are added to the vertex cover, or
						b. the vertex and its neighbours' neighbours are added to the vertex
						   cover.
			Rule #3 If there is a vertex of degree 3, either
						a. the vertex is added to the cover, or
						b. the neighbours are added to the cover.
						
		Similar to the kernelization algorithm, this process is applied to the graph 
		exhaustively. And for each iteration, the graph is kernelized again.
		
		The final output is either a "NO" if the vertex cover is empty. Otherwise:
			First Line:	 Length of vertex cover
			Second Line: Each vertex in the vertex cover, separated by a space
-}
module Main where

import BoundedSearchTree
import Char
import Datatypes
import Graph
import Kernelization
import MyIO
import MyMessages
import Words

main :: IO ()
main = do
		putStr instructions
		file <- getLine
		readInput file
		return ()

readInput :: String -> IO ()
readInput s = do
				if (s == "quit") then return () else myReadFile s

myReadFile :: FilePath -> IO ()
myReadFile file = 	if checkExtension file
					then do
						let ext = getExtension file :: FileExt
						contents <- readFile file
						let k = getK ext contents :: String	
						putStr k
						putStr "\n"
						if areDigits k then do
								let vCount = getVertexCount ext contents :: String								
								putStr vCount
								putStr "\n"
								if areDigits vCount	then do
									let actual = length $ getVertexInfo ext contents :: Int										
									if (read vCount) == actual then do
										let vInfo = getVertexInfo ext contents :: GraphInfo	
										putStr $ dispGI vInfo
										if checkLines vInfo	then do
											let graph = initializeGraph vInfo :: Graph
											--putStr $ header file
											--putStr $ debuggingGraph (k, vCount, actual, vInfo, graph)
											
											let vCover = [] :: VertexCover
											let kernelized = loopKernelization (k, graph, graph, vCover) :: Kgraph
											--putStr $ debuggingKernelization kernelized
											let search = boundSearch $ toProcessGraph kernelized :: VertexCover
											let outputString = debuggingSearchTree search
											--if (outputString == "NO")
											putStr outputString
											--let outputString = 	(header file) ++ 
											--					(debuggingGraph (k, vCount, actual, vInfo, graph)) ++ 
											--					(debuggingKernelization kernelized) ++
											--					(debuggingSearchTree search) :: String
											putStr askSave
											choice <- getLine
											if map toUpper choice == "Y" then do
												putStr enterFileName
												saveFile <- getLine
												writeFile (saveFile ++ ".txt") outputString
												putStr "\n"
												main 
											else if map toUpper choice == "N" then do 
												putStr "\n"
												main 
											else do 
												putStr wrongCmd 
												main
										else putStr errorGInfo
									else putStr errorVertexSpec 
								else putStr $ "Vertex Count: " ++ vCount ++ "\n" ++ errorVertexCount 
						else putStr $ "K: " ++ k ++ "\n" ++ errorK 
					else putStr errorFileExt